<?php
	class PaypalPaymentHandler extends AbstractPaymentHandler
	{
		protected $fieldProperties = array();
		
		function __construct()
		{
			$this->fieldProperties  = array(
			'sandbox' => array("label"=>__("Enable Sandbox"),'type'=>"select",'options'=>array(__("No"),__("Yes")),'default'=>0),
			'paypal_account' => array('label'=>__("Paypal Email"),"type"=>"text",'validate'=>array("rule"=>'email','message'=>__("Please enter a valid Email"),'allowEmpty'=>false)),
			);
		}
		
		function process(AppController $ctrl,$orderId)
		{
			$ctrl->redirect(array('plugin'=>"paid_listings","controller"=>"payments",'action'=>"paypal",$orderId));
		}
		
		function getWebStandardPaymentInformation($order,$listingPlan)
		{
			$variables = array(
				'amount' => $order['Order']['price'],
				'item_name' => $listingPlan['ListingPlan']['plan_name'],
				'tax_rate' => $order['Order']['tax'],
				'currency_code' => $order['Order']['currency'],
				//'invoice' => $order['Order']['id'],
				'business' => $this->getFieldValue('paypal_account'),	
			);
			//https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_Appx_websitestandard_htmlvariables
			$variables['cmd'] = '_xclick';
			if($order['Order']['payment_type'] == Plan::PAYMENT_SUBSCRIPTION)
			{
				//subscription don't support taxes
				unset($variables['amount'],$variables['tax_rate']);
				$variables['a3'] =  $order['Order']['total_amount'];
				$periodMap = $this->getPeriodMap();	
				$variables['cmd'] = '_xclick-subscriptions';
				$p3 = $periodMap[$order['Order']['duration_period']];
				$variables['t3'] = $p3;
				$variables['p3'] = $order['Order']['duration_number'];
				$variables['src'] = 1;
				$variables['sra'] = 1;
			}
			$variables['rm'] = 1;
			$variables['no_shipping'] = 1;
			return $variables;
		}
		
		function getPeriodMap()
		{
			return array(
				'days' => "D",
				'weeks' => "W",
				'months'=>"M",
				'years' => "Y"
			);
		}
		
		function getPaypalUrl()
		{
			$paypalUrl = "https://www.paypal.com/cgi-bin/webscr";
			if($this->getFieldValue('sandbox') == 1)
			{
				$paypalUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr";
			}
			return $paypalUrl;
		}
		
		function validateIpn($post)
		{
			$req = 'cmd=_notify-validate';
			foreach ($post as $key => $value) 
			{
				$value = urlencode(stripslashes($value));
				$req .= "&$key=$value";
			}
			// post back to PayPal system to validate
			$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
			$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
			$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
			$url = $this->getPaypalUrl();
			$urlParts = parse_url($url);
			//$urlParts['host'] = str_replace('www.', '', $urlParts['host']);
			$fp = fsockopen ('ssl://'.$urlParts['host'], 443, $errno, $errstr, 30);
			// assign posted variables to local variables
			if (!$fp) 
			{
				return false;
			} else 
			{
				fputs ($fp, $header . $req);
				$valid = false;
				while (!feof($fp)) 
				{
					$res = fgets ($fp, 1024);
					if (strcmp ($res, "VERIFIED") === 0) 
					{
						$valid= true;
						break;
						// process payment
					}else if (strcmp ($res, "INVALID") === 0) 
					{
						$valid = false;
						//$this->log(array($_POST,$planPaymentId),"failed_ipn");
						break;
					}
				}
				fclose ($fp);
			}
			return $valid;
		}
		
		function validateOrder($post,$order,$listingPlan)
		{
			if($post['business'] != $this->getFieldValue('paypal_account') || (isset($post['test_ipn']) && $post['test_ipn'] == 1 && $this->getFieldValue('sandbox') != 1))
			{
				$this->log("invalid account");
				$this->log(array($post['business'],$this->getFieldValue('paypal_account')));
				$this->log($this->getFieldValue('sandbox'));
				return false;
			}
			//verify amount.
			if(up($post['mc_currency']) == up($order['Order']['currency']) && $this->validateAmount($order['Order']['total_amount'], $post['mc_gross']))
			{
				if(low($post['payment_status']) == "completed")
				{
					return true;
				}
				$this->log("invalid statays");
			}
			$this->log(array(up($post['mc_currency']),up($order['Order']['currency']),$order['Order']['total_amount'],$post['mc_gross'],"e"=>$this->validateAmount($order['Order']['total_amount'], $post['mc_gross'])));
			return false;
		}
		//check by error margin
		protected function validateAmount($amount1,$amount2)
		{
			$amounDiff = $amount2 - $amount1;
			$amounDiff = abs((float)$amounDiff);
			$error = ($amounDiff/$amount1)*100;
			if($error < 2)
			{
				return true;
			}	
			return false;
		}
		
		protected function log($msg,$file = "payment")
		{
			uses("cake_log");
			if(!is_string($msg))
			{
				$msg = print_r($msg,true);
			}
			CakeLog::write($file,$msg);
		}
	}
?>